package site.yunnong.atvris.portal.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import site.yunnong.atvris.common.api.Result;
import site.yunnong.atvris.common.api.ResultCodeEnum;
import site.yunnong.atvris.common.exception.YunnongBusinessException;

//import javax.validation.ConstraintViolationException;

/**
 * 全局异常处理
 * @author zjh
 * @date 2021年-04月-10日
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler(value = Exception.class)
    public Result handleException(Exception e) {
        if (e instanceof MethodArgumentNotValidException) {
            return handleMethodArgumentNotValidException((MethodArgumentNotValidException) e);
        } else if (e instanceof BindException) {
            return handleBindExceptionException((BindException) e);
        } else if (e instanceof MissingServletRequestParameterException) {
            return handleMissingServletRequestParameterException((MissingServletRequestParameterException) e);
//        } else if (e instanceof ConstraintViolationException) {
//            return handleConstraintViolationException((ConstraintViolationException) e);
        } else if (e instanceof IllegalArgumentException) {
            // 业务校验异常
            return handleIllegalArgumentException((IllegalArgumentException) e);
        } else if (e instanceof YunnongBusinessException) {
            return handleYunnongBusinessException((YunnongBusinessException) e);
        } else if (e instanceof MaxUploadSizeExceededException) {
            return handleUploadException((MaxUploadSizeExceededException) e);
        } else {
            return otherException(e);
        }
    }

    private Result otherException(Exception e) {
        return new Result().fail(ResultCodeEnum.ERROR_SERVER);
    }

    private Result handleYunnongBusinessException(YunnongBusinessException e) {
        return new Result().fail(e.getResultCode(), e.getMessage());
    }

    private Result handleIllegalArgumentException(IllegalArgumentException e) {
        return new Result().fail(ResultCodeEnum.ERROR_PARAM_ILLEGAL);
    }

    /**
     * controller类添加Validated主键，针对接口单个参数时校验
     *
     * @param e
     * @return
     */
//    private Result handleConstraintViolationException(ConstraintViolationException e) {
//        return new Result().fail(ResultCodeEnum.VALIDATE_FAILED);
//    }

    /**
     * @param e
     * @return
     * @RequestParam 注解required=true时，参数属性必须存在
     */
    private Result handleMissingServletRequestParameterException(MissingServletRequestParameterException e) {
        return new Result().fail(ResultCodeEnum.ERROR_PARAM_ILLEGAL);
    }

    private Result handleBindExceptionException(BindException e) {
        String message = message(e.getBindingResult());
        return new Result().fail(ResultCodeEnum.ERROR_PARAM_ILLEGAL, message);
    }

    private Result handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        String message = message(e.getBindingResult());
        return new Result().fail(ResultCodeEnum.ERROR_PARAM_ILLEGAL, message);
    }

    private String message(BindingResult result) {
        if (result == null) {
            return "参数错误";
        }

        StringBuilder sb = new StringBuilder();
        result.getAllErrors().forEach((error) -> {
            String fieldName = ((FieldError) error).getField();
            String errorMessage = error.getDefaultMessage();
            sb.append(fieldName).append(errorMessage).append(". ");
        });

        return sb.toString();
    }

    public Result handleUploadException(MaxUploadSizeExceededException e) {
        return new Result().fail(ResultCodeEnum.ERROR_BUSINESS, "上传文件大小超出限制");
    }
}

